package com.atguigu.gmall.item.service;

import com.atguigu.gmall.common.bean.ResponseVo;
import com.atguigu.gmall.common.exception.ItemException;
import com.atguigu.gmall.item.feign.GmallPmsClient;
import com.atguigu.gmall.item.feign.GmallSmsItemClient;
import com.atguigu.gmall.item.feign.GmallWmsClient;
import com.atguigu.gmall.item.vo.ItemVo;
import com.atguigu.gmall.pms.api.GmallPmsApi;
import com.atguigu.gmall.pms.entity.*;
import com.atguigu.gmall.pms.vo.ItemGroupVo;
import com.atguigu.gmall.pms.vo.SaleAttrValueVo;
import com.atguigu.gmall.sms.vo.ItemSaleVo;
import com.atguigu.gmall.wms.entity.WareSkuEntity;
import io.netty.util.concurrent.CompleteFuture;
import net.bytebuddy.implementation.bytecode.Throw;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.ExchangeBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.Thymeleaf;
import org.thymeleaf.context.Context;


import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

/**
 * @author Jia Fa
 * @create 2021-12-15 0:57
 */
@Service
public class ItemService {

    @Autowired
    GmallPmsClient pmsClient;
    @Autowired
    GmallSmsItemClient smsClient;
    @Autowired
    GmallWmsClient wmsClient;
    @Autowired
    ExecutorService executorService;
    @Autowired
    TemplateEngine templateEngine;  // 模板引擎


    public ItemVo loadItem(Long skuId) {

        ItemVo itemVo = new ItemVo();
        // CompleteFuture 用来初始化线程
        // 异步编排线程  有返回结果集无参数
        CompletableFuture<SkuEntity> skuFuture = CompletableFuture.supplyAsync(() -> {

            // 根据skuId查询sku的信息1 很多信息需要基于SkuEntity信息
            ResponseVo<SkuEntity> skuEntityResponseVo = this.pmsClient.querySkuById(skuId);
            SkuEntity skuEntity = skuEntityResponseVo.getData();
            if (skuEntity == null) {
                throw new ItemException("不存在该商品");
            }
            itemVo.setSkuId(skuId);
            itemVo.setTitle(skuEntity.getTitle());
            itemVo.setSubTitle(skuEntity.getSubtitle());
            itemVo.setPrice(skuEntity.getPrice());
            itemVo.setWeight(skuEntity.getWeight());
            itemVo.setDefaultImage(skuEntity.getDefaultImage());
            return skuEntity;  // 无参数有返回值  返回值供下面线程使用
        }, executorService);


        // 此线程需要sku的信息  串行化方法：thenAcceptAsync获取上一个任务的返回结果，但是没有自己的结果
        CompletableFuture<Void> cateFuture = skuFuture.thenAcceptAsync(skuEntity -> {

            // 根据cid3查询分类信息2
            ResponseVo<List<CategoryEntity>> CategoryResponseVo = this.pmsClient.categories123ByCid3(skuEntity.getCategoryId());
            List<CategoryEntity> categoryEntityList = CategoryResponseVo.getData();

            itemVo.setCategoryEntities(categoryEntityList);
        }, executorService);


        // 根据品牌id查询品牌
        CompletableFuture<Void> brandFuture = skuFuture.thenAcceptAsync(skuEntity -> {

            ResponseVo<BrandEntity> brandEntityResponseVo = this.pmsClient.queryBrandById(skuEntity.getBrandId());
            BrandEntity brandEntity = brandEntityResponseVo.getData();
            if (brandEntity != null) {

                itemVo.setBrandId(brandEntity.getId());
                itemVo.setBrandName(brandEntity.getName());
            }
        }, executorService);

//        4.根据spuId查询spu信息 X
        CompletableFuture<Void> spuFuture = skuFuture.thenAcceptAsync(skuEntity -> {

            ResponseVo<SpuEntity> spuEntityResponseVo = this.pmsClient.querySpuById(skuEntity.getSpuId());
            SpuEntity spuEntity = spuEntityResponseVo.getData();
            itemVo.setSpuId(spuEntity.getId());
            itemVo.setSpuName(skuEntity.getName());
        }, executorService);

//        5.根据skuId查询sku的图片列表信息  X     runAsync无参数无返回值
        CompletableFuture<Void> imagesFuture = CompletableFuture.runAsync(() -> {

            ResponseVo<List<SkuImagesEntity>> skuImagesResponseVo = this.pmsClient.querySkuImagesBySid(skuId);
            List<SkuImagesEntity> skuImagesEntities = skuImagesResponseVo.getData();
            itemVo.setSkuImages(skuImagesEntities);
        }, executorService);

//        6.根据skuId查询sku的营销信息 X
        CompletableFuture<Void> skuAttrValueFuture = CompletableFuture.runAsync(() -> {

            ResponseVo<List<ItemSaleVo>> saleSmsResponseVo = this.smsClient.queryItemSaleBySkuId(skuId);
            List<ItemSaleVo> itemSmsSaleVoList = saleSmsResponseVo.getData();
            itemVo.setSales(itemSmsSaleVoList);
        }, executorService);

//        7.根据skuId查询sku的库存信息 X queryWareSkuBySid
        CompletableFuture<Void> wareFuture = CompletableFuture.runAsync(() -> {

            ResponseVo<List<WareSkuEntity>> wareResponseVo = this.wmsClient.queryWareSkuBySid(skuId);
            List<WareSkuEntity> wareSkuEntities = wareResponseVo.getData();
            if (!CollectionUtils.isEmpty(wareSkuEntities)) {
                // 库存信息
                itemVo.setStore(wareSkuEntities.stream().anyMatch(wareSkuEntity -> wareSkuEntity.getStock() - wareSkuEntity.getStockLocked() > 0));
            }
        }, executorService);
//        8.根据spuId查询spu下所有sku的销售属性  X  querySkuSaleAttrValueBySpuId
        CompletableFuture<Void> skuAttrValuesFuture = skuFuture.thenAcceptAsync(skuEntity -> {

            ResponseVo<List<SaleAttrValueVo>> skuSaleAttrsResponseVo = this.pmsClient.querySkuSaleAttrValueBySpuId(skuEntity.getSpuId());
            List<SaleAttrValueVo> skuSaleAttrsResponseVoData = skuSaleAttrsResponseVo.getData();
            itemVo.setSaleAttrs(skuSaleAttrsResponseVoData);
        }, executorService);

//        9.根据skuId查询sku的销售属性    querySaleAttrValuesBySkuId   { 4:'暗夜',5:'8G',6:'128G' }
        CompletableFuture<Void> SaleAttrFuture = CompletableFuture.runAsync(() -> {

            ResponseVo<List<SkuAttrValueEntity>> skuAttrResponseVo = this.pmsClient.querySaleAttrValuesBySkuId(skuId);
            List<SkuAttrValueEntity> skuAttrValueEntities = skuAttrResponseVo.getData();
            if (!CollectionUtils.isEmpty(skuAttrValueEntities)) {
                // 转为map
                Map<Long, String> map = skuAttrValueEntities.stream().collect(Collectors.toMap(SkuAttrValueEntity::getAttrId, SkuAttrValueEntity::getAttrValue));
                itemVo.setSaleAttr(map);
//            itemVo.setSaleAttr(skuAttrValueEntities.stream().collect(Collectors.toMap(SkuAttrValueEntity::getAttrId,SkuAttrValueEntity::getAttrValue));

            }
        }, executorService);

        CompletableFuture<Void> mappingFuture = skuFuture.thenAcceptAsync(skuEntity -> {

//        10.根据spuId查询spu下所有销售属性与skuId的映射关系map  querySaleWithSkuIdMappingBySpuId
            ResponseVo<String> stringResponseVo = this.pmsClient.querySaleWithSkuIdMappingBySpuId(skuEntity.getSpuId());
            String json = stringResponseVo.getData();
            itemVo.setSkuJsons(json);
        }, executorService);

//        11.根据spuId查询spu的描述信息 X  List<String> spuImages
        CompletableFuture<Void> spuImagesFuture = skuFuture.thenAcceptAsync(skuEntity -> {

            ResponseVo<SpuDescEntity> spuDescEntityResponseVo = this.pmsClient.querySpuDescById(skuEntity.getSpuId());
            SpuDescEntity spuDescEntity = spuDescEntityResponseVo.getData();
            if (spuDescEntity != null) {
                String[] images = StringUtils.split(spuDescEntity.getDecript(), ",");
                itemVo.setSpuImages(Arrays.asList(images));
            }
        }, executorService);

        CompletableFuture<Void> groupFuture = skuFuture.thenAcceptAsync(skuEntity -> {

//        12.根据分类id，skuId，spuId查询分组及组下的规格参数和值
            ResponseVo<List<ItemGroupVo>> groupsResponseVo = this.pmsClient.queryGroupWithAttrAndValueByCidAndSpuIdAndSkuId(skuEntity.getCategoryId(), skuId, skuEntity.getSpuId());
            List<ItemGroupVo> groupsResponseVoData = groupsResponseVo.getData();
            itemVo.setGroups(groupsResponseVoData);
        }, executorService);

        //等到12 个线程执行完成后再执行main 线程   join()阻塞线程
        CompletableFuture.allOf(cateFuture, brandFuture, spuFuture, imagesFuture, skuAttrValueFuture, wareFuture, skuAttrValuesFuture, SaleAttrFuture, mappingFuture, spuImagesFuture, groupFuture).join();


//        this.generateHtml(itemVo);
        CompletableFuture.runAsync(()->{
            this.generateHtml(itemVo);
        }, executorService);

        return itemVo;
    }

    // 生成静态页面
    public void generateHtml(ItemVo itemVo) {
        executorService.execute(() -> {

            try (PrintWriter printWriter = new PrintWriter("D:\\HTMl_workSpace\\item_html\\" + itemVo.getSkuId() + ".html")) {
                // Thymeleaf 上下文对象 通过其为模板传递数据
                Context context = new Context();
                context.setVariable("itemVo", itemVo);
                // 1  模板对象  2 - 上下文对象  3-写出静态页面位置
                this.templateEngine.process("item", context, printWriter);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        });
    }
}



